#pragma once

#include <iostream>
#include <vector>
#include "Sem.hpp"

namespace RingBufferModule
{
    using namespace SemModule;
    template<class T>
    class RingBuffer
    {
    public:
        RingBuffer(int cap):
        _ring(cap),
        _cap(cap),
        _p_step(0),
        _c_step(0),
        _datasem(0),
        _spacesem(cap)
        {
            
        }
        void Equeue(const T& in)
        {
            //生产者
            _spacesem.P();

            _ring[_p_step] = in;
            _P_step++;
            _p_step %= _cap;

            _datasem.V();
        }
        void Pop(T* out)
        {
            //消费者
            _datasem.P();

            *out = _ring[_c_step];
            _c_step++;
            _c_step %= _cap;

            _spacesem.V();
        }
        ~RingBuffer()
        {

        }
    private:
        std::vector<T> _ring;    //环,临界资源
        int _cap;                //容量
        int _p_step;             //生产者位置
        int _c_step;             //消费者位置
        
        Sem _datasem;          //数据信号量
        Sem _spacesem;         //空间信号量
    };
}

